<template>
  <div :class="['bk-select',{'bk-select-visible': isActive || isHover && !disabled},{'bk-select-error':isError},`bk-select-${this.size}`,{'bk-select-disabled':disabled}]"
       ref="bk-select">
    <layer v-model="showLayer"
           :autoDirection="false"
           placeX="left"
		   :shadow="true"
		   ref="layer"
		   @bodyHeight="setMenuHeight"
		   >
      <div slot="button"
           class="bk-select-selection"
           tabindex="1"
           v-clickOUtSide="handleClose"
           @click="showOption"
           @mouseenter="mouseEvent(true)"
           @mouseleave="mouseEvent(false)"
           @keydown.down.prevent="focusEvent('next')"
           @keydown.up="focusEvent('prev')"
           @keydown.enter="setselect">
        <span ref="bk-select-placeholder"
              class="bk-select-placeholder"
              v-show="isEmpty && !filterable">{{placeholder}}</span>
        <span ref="bk-select-selected-value"
              class="bk-select-selected-value"
              v-show="!isEmpty && !filterable">{{queryLabel}}</span>
        <input type="text"
               ref="bk-select-input"
               class="bk-select-input"
               :placeholder="placeholder"
               v-show="filterable"
               v-model="queryLabel"
               @keyup="OnInputChange"
               @focus="inputFocus"
               :disabled="disabled">
        <i :class="['bk-select-caret',{'up': isActive},{'down': !isActive}]"
           v-if="!isClear"
           @click.stop></i>
        <i v-if="isClear"
           class="bk-select-caret-x"
           @click.stop="clearLabel">&times;</i>
      </div>
      <div class="bk-select-error-tip"
           v-if="false">{{errText}}</div>
      <!--    <transition name="fade"> -->
      <div slot="body"
           class="bk-select-dropdown"
           ref="select-dropdown"
           v-show="isActive">
        <bk-select-menu @toBottom="toBottom" :maxHeight='maxHeight'>
          <bk-option v-for="(item,index) in queryOption"
                     ref='content'
                     :value="item"
                     @selects="selected"
                     :key="item.id || queryOption.length"
                     v-if="isActive && queryOption.length>0 && isQuery"
                     v-html="item.tpl !== undefined?translateTpl(item.tpl,item):item.name.replace('@','＠')">
          </bk-option>
          <!--  <slot v-if="showSlot && out"></slot> -->
          <!-- name里面存在@会造成浏览器卡死所以无奈地替换了下 -->
          <bk-option v-for="(item,index) in optionData"
                     ref='content'
                     @selects="selected"
                     :value="item"
                     :key="item.id || optionData.length"
                     v-if="showSlot && !out && optionData && !isQuery"
                     :defValue="defValue"
                     　v-html="item.tpl !== undefined?translateTpl(item.tpl,item):item.name.replace('@','＠')"
                     :isFocus="tabindex === index"
                     　></bk-option>
          <p class="bk-select-msg"
             v-if="queryOption.length === 0 && !showSlot && filterable">{{queryText}}</p>
          <p class="bk-select-msg"
             v-if="showSlot && loading">
            <Spin>
              <Icon type="load-c"
                    size=18
                    class="select-icon-load"></Icon>
            </Spin>
          </p>
          <p class="bk-select-msg"
             v-if="showSlot && !loading && !optionData.length">未获取到数据</p>
        </bk-select-menu>
      </div>
      <!--  </transition> -->
    </layer>
  </div>

</template>
<script>
import './style.less';
import clickOUtSide from '@/directives/click-out';
import transferDom from '@/directives/transfer-dom';
import BkSelectMenu from './select-menu';
import bkOption from './option';
import layer from '@/element/layer';
export default {
	name: 'BkSelect',
	components: {
		bkOption,
		BkSelectMenu,
		layer,
	},
	directives: { clickOUtSide, transferDom },
	props: {
		value: [Object, String, Number],
		data: [String, Array, Object],
		initData: Array,
		placeholder: {
			type: String,
			default() {
				return '请选择';
			},
		},
		filterable: {
			type: Boolean,
			default() {
				return false;
			},
		},
		size: {
			type: String,
			default() {
				return 'm';
			},
		},
		clearable: Boolean,
		required: Boolean,
		disabled: Boolean,
		loading: Boolean,
		allOption: Boolean
	},
	data() {
		return {
			transfer: true,
			out: false,
			isActive: false,
			isHover: false,
			isError: false,
			errText: '',
			isClear: false,
			currentLabel: '',
			optionList: [],
			timeout: '',
			queryOption: [],
			queryText: '无匹配数据',
			queryLabel: '',
			isQuery: false,
			showSlot: true,
			isSelect: false,
			tabindex: -1,
			showLayer: false,
			maxHeight: 200
		};
	},
	computed: {
		optionData() {
			if (this.allOption) {
				let data = this.formatData(this.data);
				data.push({ id: '', name: '全部' });
				return data;
			} else {
				return this.formatData(this.data);
			}
		},
		defValue() {
			if (typeof this.value === 'object') {
				if (this.value === null) {
					return '';
				} else {
					if (Object.keys(this.value)) {
						return this.value.id;
					} else {
						return '';
					}
				}
			} else if (typeof this.value === 'string' || typeof this.value === 'number') {
				return this.value;
			} else {
				return '';
			}
		},
		isEmpty() {
			return this.value === '' || this.value === null || this.value === undefined;
		},
	},
	watch: {
		loading: function(val) {
			if (val) {
				this.queryText = '数据获取中...';
			} else {
				this.queryText = '无匹配数据';
				this.queryOption = this.optionData.map(val => val);
				if (this.showLayer) {
					this.$refs.layer.resize()
				}
			}
		},
		defValue: function(val) {
			this.initSet();
		},
		isEmpty(val) {
			if (val) {
				this.clearLabel();
			}
		},
		isActive(val) {
			this.$nextTick(() => {
				this.showLayer = val;
			})
			if (!val) {
			this.maxHeight = 200;
			}
		}
	},
	methods: {
		setMenuHeight(val) {
           this.maxHeight = val;
		},
		formatData(param) {
			if (Array.isArray(param)) {
				return param;
			} else if (!Array.isArray(param) && typeof param === 'object' && param instanceof Object) {
				let data = [];
				Object.keys(param).forEach(v => {
					data.push({
						id: v,
						name: param[v],
					});
				});
				return data;
			} else if (typeof param === 'string') {
				let data = [];
				if (param.indexOf('@') !== -1) {
					let arr = param.split('@');
					arr.forEach(v => {
						data.push({
							id: v.split(':')[0],
							name: v.split(':')[1],
						});
					});
				}
				return data;
			} else {
			}
		},
		showOption(event) {
			if (!this.disabled) {
				this.isActive = !this.isActive;
				if (this.isActive === true) {
					this.showSlot = true;
					this.$emit('showList');
					this.$nextTick(() => {
						// let bd = document.getElementsByTagName('body')[0];
						let offsetX = event.offsetX || event.layerX;
						// let offsetY = event.offsetY || event.layerY;
						let x = event.clientX - offsetX;
						// let y = event.clientY - offsetY + event.target.parentNode.clientHeight;
						// let scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
						// y = y + scrollTop;
						// this.$refs['select-dropdown'].style.left = x + "px";
						// this.$refs['select-dropdown'].style.top = y + "px";
						this.$refs['select-dropdown'].style.minWidth = event.target.parentNode.clientWidth + 'px';
						this.$refs['select-dropdown'].style.maxWidth = document.body.clientWidth - x + 'px';
					});
				} else {
					this.$emit('closeList');
					this.$refs['bk-select-input'].blur();
				}
			}
		},
		handleClose() {
			this.queryLabel = this.currentLabel;
			this.isActive = false;
			this.$emit('closeList');
			this.queryOption = [];
			this.isQuery = false;
			this.tabindex = -1;
		},
		OnInputChange(e) {
			this.showSlot = false;
			this.isQuery = true;
			clearTimeout(this.timeout);
			if (this.queryLabel.trim() !== '') {
				this.timeout = setTimeout(() => {
					this.$emit('inputFocus', this.queryLabel.trim());
					this.queryOption = [];
					// this.query();
				}, 300);
			}
		},
		query() {
			if (this.queryLabel.trim()) {
				this.queryOption = this.optionData.filter(val => {
					if (val.name.indexOf(this.queryLabel.trim()) !== -1) {
						return val;
					}
				});
			}
		},
		mouseEvent(val) {
			if (!this.disabled) {
				this.isHover = val;
				if (this.isHover === true && this.clearable === true) {
					if (this.queryLabel !== '') {
						this.isClear = true;
					}
				}
				if (this.isHover === false) {
					this.isClear = false;
				}
			}
		},
		clearLabel() {
			this.queryLabel = '';
			this.currentLabel = '';
			this.$emit('input', '');
			this.$emit('clearSelect');
			this.$emit('selectChange', {});
		},
		scroll() {
			let el = this.$refs['content'][this.tabindex].$el;
			if (el.offsetTop - 200 > 0) {
				el.parentNode.scrollTop = el.offsetTop - 200 + el.clientHeight;
			} else {
				el.parentNode.scrollTop = 0;
			}
		},
		focusEvent(val) {
			if (this.$refs.content) {
				if (val === 'next') {
					this.tabindex++;
					if (this.tabindex > this.$refs['content'].length - 1) {
						this.tabindex = 0;
					}
					this.scroll();
				} else {
					if (this.tabindex === -1) {
						this.tabindex = this.$refs['content'].length;
						this.scroll();
					} else {
						this.tabindex--;
						if (this.tabindex < 0) {
							this.tabindex = this.$refs['content'].length - 1;
						}
						this.scroll();
					}
				}
			}
		},
		error() {
			if (this.currentLabel === '') {
				this.isError = true;
				this.errText = '选择结果不能为空';
			} else {
				this.isError = false;
			}
		},
		translateTpl(val, item) {
			var ar = val.replace(/\{/g, '{item.');
			let tpl = eval('`' + ar + '`');
			return tpl;
		},
		inputFocus() {
			this.$refs['bk-select-input'].select();
		},
		selected(item) {
			this.isSelect = true;
			if (item.tpl) {
				this.currentLabel = this.translateTpl(item.tpl, item);
			} else {
				this.currentLabel = item.name;
			}
			this.$emit('input', item.id);
			this.$emit('selectChange', item);
		},
		toBottom() {
      this.$emit('toBottom');
		},
		setselect() {
			if (this.tabindex === -1) {
				this.$refs['content'][0].select();
				this.handleClose();
			} else {
				this.$refs['content'][this.tabindex].select();
				this.handleClose();
			}
		},
		initSet() {
			if (this.defValue !== '' && !this.isSelect && (this.initData || this.optionData)) {
				let data;
				if (this.initData) {
					data = this.initData;
				} else {
					data = this.optionData;
				}
				for (let x of data) {
					if (this.defValue === x.id) {
						this.currentLabel = x.name;
						this.queryLabel = x.name;
						break;
					}
				}
			}
		},
	},
	created() {
		if (this.$slots.default) {
			this.out = true;
		}
	},
	mounted() {
		this.$nextTick(() => {
			this.initSet();
			//判断是否有默认值
			if (typeof this.value === 'object') {
				if (this.value === null) {
					return;
				} else {
					if (!Object.keys(this.value)) {
						return;
					}
				}
				if (typeof this.value.name !== 'string') {
					this.isError = true;
					this.errText = '默认值格式不符';
				} else {
					let name = this.value.name.trim();
					if (name === '') {
						this.isError = true;
						this.errText = '默认值为空';
					} else {
						this.currentLabel = this.value.name;
						this.queryLabel = this.value.name;
					}
				}
			}
		});
	},
};
</script>
